package com.csii.activiti.server.core.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csii.activiti.server.abstraction.entity.ActUser;
import com.csii.activiti.server.abstraction.service.ActUserService;
import com.csii.activiti.server.core.constant.*;
import com.csii.activiti.server.core.entity.ActCommonQueryDataDefinition;
import com.csii.activiti.server.core.entity.ActFlowPageData;
import com.csii.activiti.server.core.entity.ActManyCondition;
import com.csii.activiti.server.core.entity.db.*;
import com.csii.activiti.server.core.mapper.ActFlowConfigurationMapper;
import com.csii.activiti.server.core.mapper.ActFlowDataManagementMapper;
import com.csii.activiti.server.core.mapper.ActFlowFormMapper;
import com.csii.activiti.server.core.query.QueryActCommonData;
import com.csii.activiti.server.core.service.FlowDataManagementService;
import com.csii.activiti.server.core.utils.DataSourceUtils;
import com.csii.activiti.server.core.utils.FormJsonProcessUtils;
import com.csii.activiti.server.core.utils.OracleDBUtils;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.sql.Clob;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FlowDataManagementServiceImpl implements FlowDataManagementService {

    @Autowired(required = false)
    private ActFlowDataManagementMapper actFlowDataManagementMapper;

    private final String PREFIX_TABLE = "act_e_data_";

    private final String PREFIX_ID = "id_";

    private final String PREFIX_NAME = "name_";

    private final String PREFIX_REMARK = "remark_";

    private final String DATE = "date";

    private final String TIME = "time";

    private final String ID = "id";

    private final String DATE_SUPPLEMENT = " 00:00:00";

    private final String DATE_SUPPLEMENT2 = ":00:00";

    private final String TIME_SUPPLEMENT = ":00";

    private final String UPLOAD_FILE = "uploadFile";
    private final String UPLOAD_IMG = "uploadImg";

    private static final String TICKET = "ticket";
    private static final String BATCH = "batch";
    @Autowired
    private ActFlowConfigurationMapper actFlowConfigurationMapper;

    @Autowired
    private HistoryService historyService;


    @Autowired
    private ActFlowFormMapper actFlowFormMapper;

    @Autowired
    private ActUserService actUserService;

    @Value("${activity.oracle.typeName:SQL_TEXT_LIST}")
    private String oracleTypeName;

    @Value("${activity.oracle.procedureName:EXECUTE_SQL_TEXT}")
    private String oracleProcedureName;

    //private String oracleCurrentUserName;

    @PostConstruct
    public void initProcessData(){
        if (!isExecute()){
            return;
        }
        //oracle 初始化存储过程
        if (DataSourceUtils.isOracle()) {
            Set<String> procedureAndType = actFlowDataManagementMapper.queryOracleProcedureAndType();
            //oracleCurrentUserName = actFlowDataManagementMapper.queryOracleCurrentUserName();
            //初始化类型
            if (!procedureAndType.contains(oracleTypeName+"TYPE")){
                //actFlowDataManagementMapper.dropOracleType(oracleCurrentUserName,oracleTypeName);
                actFlowDataManagementMapper.initOracleType(oracleTypeName);
            }
            //初始化存储过程
            if (!procedureAndType.contains(oracleProcedureName+"PROCEDURE")){
                //actFlowDataManagementMapper.dropOracleProcedure(oracleCurrentUserName,oracleProcedureName);
                actFlowDataManagementMapper.initOracleProcedure(oracleProcedureName,oracleTypeName);
            }
        }


        //获取所有表名
        Set<String> tables = actFlowDataManagementMapper.queryTables();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String emptyStr = "";
        //获取所有流程
        List<ActFlowConfigurationEntity> flowList = actFlowConfigurationMapper.selectList(new LambdaQueryWrapper<ActFlowConfigurationEntity>().select(ActFlowConfigurationEntity::getFlowName,ActFlowConfigurationEntity::getFlowKey,ActFlowConfigurationEntity::getLastDeploymentId,ActFlowConfigurationEntity::getFlowColumnJson,ActFlowConfigurationEntity::getId).eq(ActFlowConfigurationEntity::getPublish, true).eq(ActFlowConfigurationEntity::getPattern, ApprovalConfigConstant.PATTERN_FORM));
        for (ActFlowConfigurationEntity flow : flowList) {
            String tableName = getTableName(flow.getFlowKey());
            //不存在直接初始化
            if (!tables.contains(tableName)){
                String lastDeploymentId = flow.getLastDeploymentId();
                List<ActCommonDataEntity> currentCommonDataList = flow.toColumnData();
                if (currentCommonDataList == null){
                    String jsonData = actFlowFormMapper.selectById(lastDeploymentId).getJsonData();
                    currentCommonDataList = FormJsonProcessUtils.formJsonProcessToCommonData(JSONObject.parseObject(jsonData));
                    ActFlowConfigurationEntity updateEntity = new ActFlowConfigurationEntity();
                    updateEntity.setId(flow.getId());
                    updateEntity.setFlowColumnJson(JSONObject.toJSONString(currentCommonDataList));
                    actFlowConfigurationMapper.updateById(updateEntity);
                }
                //初始化表
                publishDataProcess(new ArrayList<>(),currentCommonDataList,flow.getFlowKey(),flow.getFlowName());

                List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().processDefinitionKey(flow.getFlowKey()).list();
                if (list.isEmpty()){
                    continue;
                }
                Set<String> lastDeploymentIds = list.stream().map(HistoricProcessInstance::getDeploymentId).collect(Collectors.toSet());
                List<ActFlowFormEntity> flowFormDefinition = actFlowFormMapper.selectBatchIds(lastDeploymentIds);
                Map<String, List<ActCommonDataEntity>> deploymentIdAndFormJsonDefinitionData = flowFormDefinition.stream().collect(Collectors.toMap(ActFlowFormEntity::getId, item-> FormJsonProcessUtils.formJsonProcessToCommonData(JSONObject.parseObject(item.getJsonData()),false)));
                List<Map<String, Object>> dataList = new ArrayList<>();
                for (HistoricProcessInstance historicProcessInstance : list) {
                    String id = historicProcessInstance.getId();
                    HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(id).variableName(CommonConstant.FORM_DATA).singleResult();
                    //获取formJson
                    List<ActCommonDataEntity> actCommonDataList = deploymentIdAndFormJsonDefinitionData.get(historicProcessInstance.getDeploymentId());
                    Map<String, String> originCommonDataDefinition = actCommonDataList.stream().collect(Collectors.toMap(ActCommonDataEntity::getId, ActCommonDataEntity::getFormAttributeName));

                    Map<String,Object> data = (Map<String, Object>) historicVariableInstance.getValue();
                    if (data == null || data.size() == 0){
                        continue;
                    }
                    Map<String,Object> formData = new HashMap<>(data.size());

                    for (ActCommonDataEntity actCommonDataEntity : currentCommonDataList) {
                        if (actCommonDataEntity.getId() != null){
                            String mapKey = originCommonDataDefinition.get(actCommonDataEntity.getId());
                            if (mapKey != null){
                                formData.put(actCommonDataEntity.getFormAttributeName(),data.get(mapKey.replace(CommonConstant.PREFIX_FORM_DATA,emptyStr)));
                            }
                        }
                    }
                    formData.put(ID,id);
                    formData.put(ActDefaultColumnConstant.INITIATOR,historicProcessInstance.getStartUserId());
                    if (historicProcessInstance.getEndTime() == null) {
                        formData.put(ActDefaultColumnConstant.STATUS, ActFlowDataManageConstant.UNDER_REVIEW.getStatus());
                    }else if (historicProcessInstance.getDeleteReason() == null){
                        formData.put(ActDefaultColumnConstant.STATUS,ActFlowDataManageConstant.PASSED.getStatus());
                    }else{
                        formData.put(ActDefaultColumnConstant.STATUS, ActFlowActionSettingConstant.REJECT.equals(historicProcessInstance.getDeleteReason())?ActFlowDataManageConstant.REJECTED.getStatus():ActFlowDataManageConstant.WITHDRAWN.getStatus());
                    }
                    formData.put(ActDefaultColumnConstant.START_TIME,sdf.format(historicProcessInstance.getStartTime()));
                    if (historicProcessInstance.getEndTime() != null){
                        formData.put(ActDefaultColumnConstant.END_TIME,sdf.format(historicProcessInstance.getEndTime()));
                    }
                    dataList.add(formData);
                }

                //数据写入
                if (!dataList.isEmpty()){
                    batchAddData(flow.getFlowKey(),dataList,currentCommonDataList);
                }
            }
        }
    }

    private Map<String, String> queryUsernameAndNickname(Set<String> usernames){
        List<ActUser> actUsers = actUserService.queryUserByUsernames(usernames);
        if (CollUtil.isNotEmpty(actUsers)){
            Map<String, String> usernameAndNickname = actUsers.stream().collect(Collectors.toMap(ActUser::getUsername, ActUser::getNickname, (k1, k2) -> k2));
            return usernameAndNickname;
        }
        return new HashMap<>();
    }


    @Override
    public void publishDataProcess(List<ActCommonDataEntity> originalCommonDataList, List<ActCommonDataEntity> currentCommonDataList, String flowKey,String flowName) {
        if (!isExecute()){
            return;
        }
        String tableName = getTableName(flowKey);
        int count = actFlowDataManagementMapper.queryTableNameByCount(tableName);
        if (count == 0){
            //直接初始化表
            try {
                if (DataSourceUtils.isOracle()){
                    actFlowDataManagementMapper.batchOracleCommandExecution(oracleProcedureName, OracleDBUtils.createTableSqlText(tableName,flowName,currentCommonDataList));
                }else{
                    actFlowDataManagementMapper.createNewTable(tableName,flowName,currentCommonDataList);
                }
            }catch (Exception e){
                log.error("flowDataManagementServiceImpl datasource table init error is {}" ,e);
            }
            return;
        }
        Map<String,ActCommonDataEntity> originalCommonDataMap = new HashMap<>();

        for (ActCommonDataEntity actCommonDataEntity : originalCommonDataList) {
            String key = actCommonDataEntity.getId();
            if(key == null){
                key = actCommonDataEntity.getColumnName();
            }
            originalCommonDataMap.put(key,actCommonDataEntity);

        }

        Map<String,ActCommonDataEntity> currentCommonDataMap = new HashMap<>();

        for (ActCommonDataEntity actCommonDataEntity : currentCommonDataList) {
            String key = actCommonDataEntity.getId();
            if(key == null){
                key = actCommonDataEntity.getColumnName();
            }
            currentCommonDataMap.put(key,actCommonDataEntity);
        }

        List<ActCommonDataEntity> addColumnList = new ArrayList<>();
        Map<String,ActCommonDataEntity> addColumnNameAndEntity = new HashMap<>();

        List<ActModifyCommonDataEntity> modifyColumnList = new ArrayList<>();
        Set<String> tableColumns = actFlowDataManagementMapper.queryTableColumns(tableName);
        //查询新增的和修改的
        for (ActCommonDataEntity currentEntity : currentCommonDataList) {
            String key = currentEntity.getId();
            if (key == null){
                key = currentEntity.getColumnName();
            }
            ActCommonDataEntity originalEntity = originalCommonDataMap.get(key);
            if (originalEntity == null){
                addColumnList.add(currentEntity);
                addColumnNameAndEntity.put(currentEntity.getColumnName(), currentEntity);
            }else if (!currentEntity.equals(originalEntity)){
                if (tableColumns.contains(originalEntity.getColumnName())){
                    modifyColumnList.add(new ActModifyCommonDataEntity(originalEntity,currentEntity));
                }else{
                    addColumnList.add(currentEntity);
                    addColumnNameAndEntity.put(currentEntity.getColumnName(), currentEntity);
                }
            }

        }
        List<String> deleteColumnList = new ArrayList<>();
        //查询删除的
        for (ActCommonDataEntity originalEntity : originalCommonDataList) {
            String key = originalEntity.getId();
            if (key == null){
                key = originalEntity.getColumnName();
            }
            ActCommonDataEntity currentEntity = currentCommonDataMap.get(key);
            if (currentEntity == null && tableColumns.contains(originalEntity.getColumnName())){
                if (addColumnNameAndEntity.containsKey(originalEntity.getColumnName())){
                    //生成修改的数据
                    ActCommonDataEntity addEntity = addColumnNameAndEntity.get(originalEntity.getColumnName());
                    modifyColumnList.add(new ActModifyCommonDataEntity(originalEntity,addEntity));
                    //删除新增数据
                    addColumnList.remove(addEntity);
                    continue;
                }
                deleteColumnList.add(originalEntity.getColumnName());
            }

        }


        if (!deleteColumnList.isEmpty()){
            actFlowDataManagementMapper.deleteColumn(tableName,deleteColumnList);
        }

        if (!addColumnList.isEmpty()){
            if (DataSourceUtils.isOracle()){
                actFlowDataManagementMapper.batchOracleCommandExecution(oracleProcedureName,OracleDBUtils.addColumnSqlText(tableName,addColumnList));
            }else{
                actFlowDataManagementMapper.addColumn(tableName,addColumnList);
            }
        }
        if (!modifyColumnList.isEmpty()){
            if (DataSourceUtils.isOracle()){
                actFlowDataManagementMapper.batchOracleCommandExecution(oracleProcedureName,OracleDBUtils.modifyColumnSqlText(tableName,modifyColumnList));
            }else{
                actFlowDataManagementMapper.modifyColumn(tableName,modifyColumnList);
            }
        }

        if (flowName != null && !actFlowDataManagementMapper.queryTableComment(tableName).equals(flowName)){
            actFlowDataManagementMapper.modifyTableComment(tableName,flowName);
        }
    }

    @Override
    public Page<Map<String, Object>> queryData(QueryActCommonData queryActCommonData,Page page){
        if (!isExecute()){
            return new Page<>();
        }
        ActFlowConfigurationEntity flowConfigurationEntity = actFlowConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowConfigurationEntity>().select(ActFlowConfigurationEntity::getFlowColumnJson,ActFlowConfigurationEntity::getLastDeploymentId).eq(ActFlowConfigurationEntity::getFlowKey, queryActCommonData.getFlowKey()));
        List<ActCommonDataEntity> actCommonDataList = flowConfigurationEntity.toColumnData();
        Map<String, String> columnNameAndType = actCommonDataList.stream().collect(Collectors.toMap(ActCommonDataEntity::getColumnName, ActCommonDataEntity::getElementType, (v1, v2) -> v2));
        List<ActCommonQueryDataDefinition> queryParams = queryActCommonData.getQueryParams();
        if (CollUtil.isNotEmpty(queryParams)){
            for (ActCommonQueryDataDefinition queryParam : queryParams) {
                String type = columnNameAndType.get(queryParam.getColumnName());
                if (DATE.equals(type)){
                    queryParam.setStartData(toTimestamp(queryParam.getStartData()));
                    queryParam.setEndData(toTimestamp(queryParam.getEndData()));
                    queryParam.setData(toTimestamp(queryParam.getData()));

                }else if (TIME.equals(type)){
                    queryParam.setStartData(toTime(queryParam.getStartData()));
                    queryParam.setEndData(toTime(queryParam.getEndData()));
                    queryParam.setData(toTime(queryParam.getData()));
                }
            }
        }
        String tableName = getTableName(queryActCommonData.getFlowKey());
        Page<Map<String, Object>> result = actFlowDataManagementMapper.queryData(page,tableName, queryActCommonData.getQueryParams());
        List<Map<String, Object>> list = result.getRecords();
        if (result.getTotal() == 0){
            return result;
        }
        Set<String> usernames = list.stream().map(item -> (String) item.get(ActDefaultColumnConstant.INITIATOR)).collect(Collectors.toSet());
        Map<String, String> usernameAndNickname = new HashMap<>();
        int count = 0;
        Set<String> portionUsername = new HashSet<>();
        for (String username : usernames) {
            count ++;
            portionUsername.add(username);
            if (count == 999){
                count = 0;
                usernameAndNickname.putAll(queryUsernameAndNickname(portionUsername));
                portionUsername.clear();
            }
        }

        if (count > 0){
            usernameAndNickname.putAll(queryUsernameAndNickname(portionUsername));
            portionUsername = null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/GMT-8"));
        JSONObject jsonObject = JSONObject.parseObject(actFlowFormMapper.selectById(flowConfigurationEntity.getLastDeploymentId()).getJsonData());
        Map<String, ActManyCondition> modeAndManyCondition = FormJsonProcessUtils.recursionManyConditions(jsonObject);
        for (Map<String, Object> item : list) {
            // 兼容oracle 大写
//            if (DataSourceUtils.isOracle()){
//                String statusUpperCase = ActDefaultColumnConstant.STATUS.toUpperCase();
//                item.put(statusUpperCase,ActFlowDataManageConstant.getDescription((String) item.get(statusUpperCase)).getDescription());
//            }else{
//                item.put(ActDefaultColumnConstant.STATUS,ActFlowDataManageConstant.getDescription((String) item.get(ActDefaultColumnConstant.STATUS)).getDescription());
//            }
            item.put(ActDefaultColumnConstant.STATUS,ActFlowDataManageConstant.getDescription((String) item.get(ActDefaultColumnConstant.STATUS)).getDescription());
            for (Map.Entry<String, Object> entry : item.entrySet()) {
                Object value = entry.getValue();
                if (value != null ) {
                    ActManyCondition actManyCondition = modeAndManyCondition.get(entry.getKey());
                    if (actManyCondition != null && actManyCondition.getValAndLabel() != null){
                        if (actManyCondition.getType().startsWith("radio") || actManyCondition.getType().startsWith("select")){
                            item.put(entry.getKey(),actManyCondition.getValAndLabel().get(value.toString()));
                        }else if(actManyCondition.getType().startsWith("checkbox")){
                            List<Object> checkboxList = JSONObject.parseArray(value.toString(), Object.class);
                            if (!checkboxList.isEmpty()){
                                item.put(entry.getKey(),checkboxList.stream().map(checkbox-> {
                                    String checkboxKey = checkbox.toString();
                                    String checkboxValue = actManyCondition.getValAndLabel().get(checkboxKey);
                                    if(checkboxValue == null){
                                        return checkboxKey;
                                    }
                                    return checkboxValue;
                                }).collect(Collectors.joining(",")));
                            }
                        }
                    }else if (value instanceof Time){
                        item.put(entry.getKey(),value.toString());
                    }else if (value instanceof Timestamp){
                        item.put(entry.getKey(),dateFormat.format(new Date(((Timestamp)value).getTime())));
                    }else if (value instanceof Date){
                        item.put(entry.getKey(),dateFormat.format((Date)value));
                    }else if (value instanceof Clob){
                        item.put(entry.getKey(),clobToString((Clob) value));
                    }
                }
            }
            String username = (String) item.get(ActDefaultColumnConstant.INITIATOR);
            if (username != null){
                String nickname = usernameAndNickname.get(username);
                if (nickname != null){
                    item.put(ActDefaultColumnConstant.INITIATOR,nickname);
                }
            }
        }

        return result;
    }

    private String clobToString(Clob clob){

        String reString = "";
        try {
            java.io.Reader is = clob.getCharacterStream();
            BufferedReader br = new BufferedReader(is);
            String s = br.readLine();
            StringBuffer sb = new StringBuffer();
            while (s != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING
                sb.append(s);
                s = br.readLine();
            }
            reString = sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return reString;
    }

    @Override
    public ActFlowPageData queryPageData(String flowKey) {
        if (!isExecute()){
            return new ActFlowPageData();
        }
        ActFlowConfigurationEntity flow = actFlowConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowConfigurationEntity>().select(ActFlowConfigurationEntity::getFlowName,ActFlowConfigurationEntity::getFlowKey,ActFlowConfigurationEntity::getLastDeploymentId,ActFlowConfigurationEntity::getFlowColumnJson).eq(ActFlowConfigurationEntity::getPublish, true).eq(ActFlowConfigurationEntity::getFlowKey,flowKey));
        List<ActCommonDataEntity> currentCommonDataList = flow.toColumnData();
        String lastDeploymentId = flow.getLastDeploymentId();
        String jsonData = actFlowFormMapper.selectById(lastDeploymentId).getJsonData();
        JSONObject form = JSONObject.parseObject(jsonData);
        if (currentCommonDataList == null){
            currentCommonDataList = FormJsonProcessUtils.formJsonProcessToCommonData(form);
        }
        ActFlowPageData actFlowPageData = new ActFlowPageData();
        actFlowPageData.setColumns(currentCommonDataList);
        actFlowPageData.setFlowKey(flowKey);
        actFlowPageData.setFlowName(flow.getFlowName());
        actFlowPageData.setForm(form);
        return actFlowPageData;
    }

    @Override
    public void updateData(String flowKey, Map<String, Object> data, List<ActCommonDataEntity> commonDataList) {
        if (isExecute()){
            return;
        }
        String tableName = getTableName(flowKey);
        List<ActCommonUpdateDataEntity> updateDataList = new ArrayList<>();
        for (ActCommonDataEntity actCommonDataEntity : commonDataList) {
            Object val = data.get(actCommonDataEntity.getColumnName());
            if (val != null){
                updateDataList.add(new ActCommonUpdateDataEntity(actCommonDataEntity.getColumnName(),val));
            }
        }
        if (!updateDataList.isEmpty()){
            actFlowDataManagementMapper.commonUpdateData(tableName,updateDataList,(String) data.get(ID));
        }
    }


    @Override
    public void batchAddData(String flowKey, List<Map<String, Object>> dataList, List<ActCommonDataEntity> commonDataList) {
        if (!isExecute()){
            return;
        }
        String tableName = getTableName(flowKey);
        List<List<Object>> insertDataList = new ArrayList<>();
        ActCommonDataEntity idEntity = new ActCommonDataEntity();
        idEntity.setColumnName(ID);
        idEntity.setFormAttributeName(ID);
        commonDataList.add(idEntity);
        List<String> ids = new ArrayList<>();
        for (Map<String, Object> data : dataList) {
            List<Object> columnList = new ArrayList<>();
            for (ActCommonDataEntity actCommonDataEntity : commonDataList) {
                Object val = data.get(actCommonDataEntity.getFormAttributeName());
                if (!StrUtil.isEmptyIfStr(val)){
                    if (ID.equals(actCommonDataEntity.getFormAttributeName())){
                        ids.add(val.toString());
                    }
                    if (DATE.equals(actCommonDataEntity.getElementType())){
                        if(val instanceof List){
                            columnList.add(null);
                            continue;
                        }
                        String valStr = val.toString();
                        int length = valStr.length();
                        if (length == 10){
                            valStr = valStr + DATE_SUPPLEMENT;
                        }else if (length == 13){
                            valStr = valStr + DATE_SUPPLEMENT2;
                        }
                        try {
                            val = Timestamp.valueOf(valStr);
                        }catch (Exception e){
                            log.error("column Timestamp convertor error is {} value is {}",e , val);
                            columnList.add(null);
                            continue;
                        }
                    }else if (TIME.equals(actCommonDataEntity.getElementType())){
                        try {
                            String valStr = val.toString();
                            if (valStr.length() == 5) {
                                valStr += TIME_SUPPLEMENT;
                            }
                            val = Time.valueOf(valStr);
                        }catch (Exception e){
                            log.error("column Time convertor error is {} value is {}",e , val);
                            columnList.add(null);
                            continue;
                        }
                    }else if(val instanceof List || val instanceof Map){
                        val = JSONObject.toJSONString(val);
                    }
                    else {
                        val = val.toString();
                    }
                }
                columnList.add("".equals(val)? null : val);
            }
            insertDataList.add(columnList);
        }
        //先清除再新增
        actFlowDataManagementMapper.batchDeleteData(tableName,ids);
        actFlowDataManagementMapper.batchAddData(tableName,commonDataList,insertDataList);

    }

    @Override
    public void addData(String processInstanceId) {
        if (!isExecute()){
            return;
        }
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String processDefinitionKey = historicProcessInstance.getProcessDefinitionKey();
        ActFlowConfigurationEntity flowConfigurationEntity = actFlowConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowConfigurationEntity>().select(ActFlowConfigurationEntity::getFlowColumnJson).eq(ActFlowConfigurationEntity::getFlowKey, processDefinitionKey));
        if (flowConfigurationEntity == null){
            return;
        }
        HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName(CommonConstant.FORM_DATA).singleResult();
        List<ActCommonDataEntity> actCommonDataList = flowConfigurationEntity.toColumnData();
        Map<String, Object> data = (Map<String, Object>) historicVariableInstance.getValue();
        Map<String, Object> formData = new HashMap<>();
        if (data != null){
            for (Map.Entry<String, Object> item : data.entrySet()) {
                formData.put(CommonConstant.PREFIX_FORM_DATA + item.getKey(),item.getValue());
            }
        }
        formData.put(ID,historicProcessInstance.getId());
        formData.put(ActDefaultColumnConstant.INITIATOR,historicProcessInstance.getStartUserId());
        if (historicProcessInstance.getEndTime() == null) {
            formData.put(ActDefaultColumnConstant.STATUS,ActFlowDataManageConstant.UNDER_REVIEW.getStatus());
        }else if (historicProcessInstance.getDeleteReason() == null){
            formData.put(ActDefaultColumnConstant.STATUS,ActFlowDataManageConstant.PASSED.getStatus());
        }else{
            formData.put(ActDefaultColumnConstant.STATUS, ActFlowActionSettingConstant.REJECT.equals(historicProcessInstance.getDeleteReason())?ActFlowDataManageConstant.REJECTED.getStatus():ActFlowDataManageConstant.WITHDRAWN.getStatus());
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formData.put(ActDefaultColumnConstant.START_TIME,sdf.format(historicProcessInstance.getStartTime()));
        if (historicProcessInstance.getEndTime() != null){
            formData.put(ActDefaultColumnConstant.END_TIME,sdf.format(historicProcessInstance.getEndTime()));
        }

        if (!formData.isEmpty()){
            addData(processDefinitionKey,formData,actCommonDataList);
        }

    }

    @Override
    public void addData(Map<String, Object> formData, ExecutionEntity processInstance,String status) {
        if (!isExecute()){
            return;
        }
        String flowKey = processInstance.getProcessDefinitionKey();
        if (flowKey == null && processInstance.getProcessDefinitionId()!= null){
            flowKey = processInstance.getProcessDefinitionId().split(":")[0];
        }
        ActFlowConfigurationEntity flowConfigurationEntity = actFlowConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowConfigurationEntity>().select(ActFlowConfigurationEntity::getFlowColumnJson).eq(ActFlowConfigurationEntity::getFlowKey, flowKey));
        if (flowConfigurationEntity == null){
            return;
        }
        Map<String, Object> newFormData = new HashMap<>(formData.size());
        for (Map.Entry<String, Object> item : formData.entrySet()) {
            newFormData.put(CommonConstant.PREFIX_FORM_DATA + item.getKey(),item.getValue());
        }
        newFormData.put(ID,processInstance.getId());
        newFormData.put(ActDefaultColumnConstant.INITIATOR,processInstance.getStartUserId());
        newFormData.put(ActDefaultColumnConstant.STATUS,status);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        newFormData.put(ActDefaultColumnConstant.START_TIME,sdf.format(processInstance.getStartTime()));
        newFormData.put(ActDefaultColumnConstant.END_TIME,sdf.format(new Date()));
        List<ActCommonDataEntity> actCommonDataList = flowConfigurationEntity.toColumnData();
        addData(flowKey,newFormData,actCommonDataList);
    }

    private String getTableName(String flowKey){
        String tableName = PREFIX_TABLE + flowKey.toLowerCase();
        if (DataSourceUtils.isOracle()){
            return tableName.toUpperCase();
        }
        return tableName;
    }

    private Timestamp toTimestamp(Object val){
        if (val == null){
            return null;
        }
        String dataStr = val.toString();
        if (StrUtil.isNotBlank(dataStr)){
            int length = dataStr.length();
            if (length == 10){
                return Timestamp.valueOf(dataStr + DATE_SUPPLEMENT);
            }else if (length == 13){
                return Timestamp.valueOf(dataStr + DATE_SUPPLEMENT2);
            }
            return Timestamp.valueOf(dataStr);
        }
        return null;
    }

    private Time toTime(Object val){
        if (val == null){
            return null;
        }
        String timeStr = val.toString();
        if (timeStr.length() == 5){
            timeStr += TIME_SUPPLEMENT;
        }
        if (StrUtil.isNotBlank(timeStr)){
            return Time.valueOf(timeStr);
        }
        return null;
    }

    private boolean isExecute(){
        return this.actFlowDataManagementMapper != null;
    }
}
